package com.example.planetandzombiedemo.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Typeface;
import android.util.EventLog;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import androidx.annotation.NonNull;

import com.example.planetandzombiedemo.entity.Bullet;
import com.example.planetandzombiedemo.entity.EmplaceFlower;
import com.example.planetandzombiedemo.entity.EmplacePea;
import com.example.planetandzombiedemo.entity.Flower;
import com.example.planetandzombiedemo.entity.Pea;
import com.example.planetandzombiedemo.entity.SeedFlower;
import com.example.planetandzombiedemo.entity.SeedPea;
import com.example.planetandzombiedemo.entity.Sun;
import com.example.planetandzombiedemo.entity.Zombie;
import com.example.planetandzombiedemo.entity.ZombieManager;
import com.example.planetandzombiedemo.global.Config;
import com.example.planetandzombiedemo.model.BaseModel;
import com.example.planetandzombiedemo.model.Plantable;
import com.example.planetandzombiedemo.model.Touchable;

import java.time.zone.ZoneRulesException;
import java.util.ArrayList;

/**
 * GameView游戏核心类：继承SurfaceView类，实现回调接口以及线程接口
 **/
public class GameView extends SurfaceView implements SurfaceHolder.Callback, Runnable {

    //相关成员变量声明
    //指活动
    private Context context;
    //画布
    private Canvas canvas;
    //画笔
    private Paint paint;
    //界面托管类
    private SurfaceHolder surfaceHolder;
    //线程管理标志
    private boolean gameRunFlag;
    //GameView作为管理者，所有的实体均可向其发送请求并处理
    private static GameView gameView;
    //游戏的绘制层次序号越小越靠近游戏玩家
    //植物放置层-1层（最靠近游戏玩家的层）
    private ArrayList<BaseModel> gameLayout1;
    //植物卡片层-2层
    private ArrayList<BaseModel> gameLayout2;
    //阳光层-3层
    private ArrayList<BaseModel> gameLayout3;
    //植物跑道层-4层
    private ArrayList<BaseModel>[] gameLayout4;
    //僵尸跑道层-4层
    private ArrayList<BaseModel>[] gameLayout5;
    //待处理的无需显示的游戏资源（isAlife=false)
    private ArrayList<BaseModel> deadList;
    //僵尸控制器
    private ZombieManager zombieManager;

    /**
     * 构造方法，初始化所需资源
     *
     * @param context
     */
    public GameView(Context context) {
        super(context);
        this.context = context;
        this.paint = new Paint();
        this.surfaceHolder = this.getHolder();
        this.surfaceHolder.addCallback(this);
        this.gameRunFlag = true;
        gameView = this;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //植物放置层事件
        for (BaseModel model : gameLayout1) {
            if (model instanceof Touchable) {
                if (((Touchable) model).onTouch(event)) {
                    return true;
                }
            }
        }
        //卡片层事件
        for (BaseModel model : gameLayout2) {
            if (model instanceof Touchable) {
                if (((Touchable) model).onTouch(event)) {
                    return true;
                }
            }
        }
        //阳光层事件
        for (BaseModel model : gameLayout3) {
            if (model instanceof Touchable) {
                if (((Touchable) model).onTouch(event)) {
                    return true;
                }
            }
        }
        return super.onTouchEvent(event);
    }

    @Override
    public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
        //创建游戏元素
        createElements();
        //启动游戏核心线程
        new Thread(this).start();
    }


    @Override
    public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {

    }

    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {

    }

    @Override
    public void run() {
        while (gameRunFlag) {
            long _starttime = System.currentTimeMillis();
            //同步原语：保证操作的原子性，即不可分割
            synchronized (surfaceHolder) {
                try {
                    //获取并锁定画布
                    canvas = surfaceHolder.lockCanvas();
                    logic();
                    draw();
                } catch (Exception e) {
                    Log.e("**==MyDebug==**", "异常错误信息：" + e.getMessage());
                } finally {
                    //解锁并提交画布
                    surfaceHolder.unlockCanvasAndPost(canvas);
                }
            }
            long _endtime = System.currentTimeMillis();
            long _sleeptime = 40 - (_endtime - _starttime);
            //实现游戏的帧数 40毫秒 即25帧/秒  1秒=1000毫秒
            if (_sleeptime > 0) {
                try {
                    Thread.sleep(_sleeptime);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 游戏绘制逻辑方法:界面绘制
     */
    private void draw() {
        // canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.bk), 0, 0, paint);
        //绘制背景
        canvas.drawBitmap(Config.gameBK, 0, 0, paint);
        //绘制卡片栏
        canvas.drawBitmap(Config.seedBank, Config.seedBankLocationX, 0, paint);
        //绘制阳光值
        Paint _paint = new Paint();
        _paint.setTypeface(Typeface.DEFAULT_BOLD);
        _paint.setTextSize(15);
        canvas.drawText(Config.sunLight + "", Config.deviceWidth * 2 / 7, Config.deviceHeight / 8, _paint);
        //初始化僵尸控制器，并不在游戏中进行绘制
        zombieManager.drawSelf(canvas, paint);
        //绘制僵尸跑道层
        for (int i = 0; i < 5; i++) {
            for (BaseModel model : gameLayout5[i]) {
                model.drawSelf(canvas, paint);
            }
        }
        //绘制植物跑道层
        for (int i = 0; i < 5; i++) {
            for (BaseModel model : gameLayout4[i]) {
                model.drawSelf(canvas, paint);
            }
        }
        int a;
        //绘制阳光层
        for (BaseModel model : gameLayout3) {
            model.drawSelf(canvas, paint);
        }
        //绘制卡片层
        for (BaseModel model : gameLayout2) {
            model.drawSelf(canvas, paint);
        }
        //绘制放置层
        for (BaseModel model : gameLayout1) {
            model.drawSelf(canvas, paint);
        }
    }

    /**
     * 由flower请求，用于产生阳光
     *
     * @param locationX
     * @param locationY
     */
    public void giveBirth2Sun(int locationX, int locationY) {
        synchronized (surfaceHolder) {
            gameLayout3.add(new Sun(locationX, locationY));
        }
    }

    /**
     * 由pea请求，用于产生阳光
     *
     * @param locationX
     * @param locationY
     */
    public void giveBirth2Bullet(int locationX, int locationY) {
        synchronized (surfaceHolder) {
            Point point;
            for (Integer key : Config.plantPoints.keySet()) {
                point = Config.plantPoints.get(key);
                //判断跑道上是否存在植物
                if (Math.abs(locationX - point.x) < Config.deviceWidth / 11 / 2 &&
                        Math.abs(locationY - point.y) < Config.deviceHeight / 6 / 2) {
                    //标识需要处理的跑道
                    int raceWayIndex = 6;
                    for (int i = 0; i < Config.raceWayPoints.length; i++) {
                        if (point.y == Config.raceWayPoints[i]) {
                            raceWayIndex = i;
                        }
                    }
                    //增加子弹
                    gameLayout4[raceWayIndex].add(new Bullet(locationX, locationY));

                }
            }
        }
    }

    /**
     * 游戏核心逻辑方法：数据更新
     */
    private void logic() {
        deadList.clear();
        for (BaseModel model : gameLayout1) {
            if (!model.getisAlife()) {
                deadList.add(model);
            }
        }
        for (BaseModel model : gameLayout2) {
            if (!model.getisAlife()) {
                deadList.add(model);
            }
        }
        for (BaseModel model : gameLayout3) {
            if (!model.getisAlife()) {
                deadList.add(model);
            }
        }
        for (int i = 0; i < gameLayout4.length; i++) {
            for (BaseModel model : gameLayout4[i]) {
                if (!model.getisAlife()) {
                    deadList.add(model);
                }
            }
        }
        for (int i = 0; i < gameLayout5.length; i++) {
            for (BaseModel model : gameLayout5[i]) {
                if (!model.getisAlife()) {
                    deadList.add(model);
                }
            }
        }
        //遍历deadList集合，从各层中删除该集合中的所有元素
        for (BaseModel model : deadList) {
            gameLayout1.remove(model);
            gameLayout2.remove(model);
            gameLayout3.remove(model);
            for (int i = 0; i < gameLayout4.length; i++) {
                gameLayout4[i].remove(model);
            }
            for (int i = 0; i < gameLayout5.length; i++) {
                gameLayout5[i].remove(model);
            }
        }
    }

    /**
     * 创建游戏元素（卡片层，放置层，植物层，阳光层，僵尸层）
     */
    private void createElements() {
        //初始化游戏放置层
        gameLayout1 = new ArrayList<BaseModel>();
        //初始化游戏卡片层
        gameLayout2 = new ArrayList<BaseModel>();
        SeedFlower seedFlower = new SeedFlower((Config.deviceWidth - Config.seedBank.getWidth()) / 2 +
                Config.seedFlower.getWidth() / 3 + Config.seedBank.getWidth() / 7,
                Config.seedBank.getHeight() / 10);
        SeedPea seedPea = new SeedPea((Config.deviceWidth - Config.seedBank.getWidth()) / 2 +
                Config.seedFlower.getWidth() / 3 + Config.seedBank.getWidth() / 7 * 2,
                Config.seedBank.getHeight() / 10);
        gameLayout2.add(seedFlower);
        gameLayout2.add(seedPea);

        //初始化阳光层
        gameLayout3 = new ArrayList<BaseModel>();
        //初始化植物跑道层
        gameLayout4 = new ArrayList[5];
        for (int i = 0; i < 5; i++) {
            gameLayout4[i] = new ArrayList<BaseModel>();
        }
        //初始化僵尸跑道层
        gameLayout5 = new ArrayList[5];
        for (int i = 0; i < 5; i++) {
            gameLayout5[i] = new ArrayList<BaseModel>();
        }

        deadList = new ArrayList<BaseModel>();
        zombieManager = new ZombieManager();
    }

    /**
     * 获得唯一的管理者（GameView） 单例模式
     *
     * @return
     */
    public static GameView getInstance() {
        return gameView;
    }

    /**
     * 处理“放置”资源
     *
     * @param locationX
     * @param locationY
     * @param model
     */
    public void apply4EmplacePlant(int locationX, int locationY, BaseModel model) {
        synchronized (surfaceHolder) {
            //卡片拾取始终只有一个
            if (gameLayout1.size() < 1) {
                //加入到放置层
                if (model instanceof SeedFlower)//拾取太阳花
                {
                    gameLayout1.add(new EmplaceFlower(locationX, locationY));
                } else {//拾取豌豆卡片
                    gameLayout1.add(new EmplacePea(locationX, locationY));
                }
            }

        }
    }

    /**
     * 处理植物资源
     *
     * @param locationX
     * @param locationY
     * @param model
     */
    public void apply4Plant(int locationX, int locationY, BaseModel model) {
        synchronized (surfaceHolder) {
            //把locationX与locationY置换为指定的Point
            Point point;
            for (Integer key : Config.plantPoints.keySet()) {
                point = Config.plantPoints.get(key);
                //在指定Point所代表的矩形区域中
                if (Math.abs(locationX - point.x) < Config.deviceWidth / 11 / 2 &&
                        Math.abs(locationY - point.y) < Config.deviceHeight / 6 / 2) {
                    //标识需要处理的跑道
                    int raceWayIndex = 6;
                    for (int i = 0; i < Config.raceWayPoints.length; i++) {
                        if (point.y == Config.raceWayPoints[i]) {
                            raceWayIndex = i;
                        }
                    }
                    if (isPlantExist(key, raceWayIndex))//不存在
                    {
                        if (model instanceof EmplaceFlower) {
                            gameLayout4[raceWayIndex].add(new Flower(point.x, point.y, key));
                            Config.sunLight -= 50;
                        } else {
                            gameLayout4[raceWayIndex].add(new Pea(point.x, point.y, key));
                            Config.sunLight -= 100;
                        }
                    }
                }
            }
        }
    }

    /**
     * 僵尸控制器
     */
    public void apply4Zombie() {
        synchronized (surfaceHolder) {
            //随机化初始化跑道
            int raceWay = 0;
            raceWay = (int) (Math.random() * 5);
            gameLayout5[raceWay].add(new Zombie(Config.deviceWidth + 20,//从屏幕外进入游戏画面
                    Config.raceWayPoints[raceWay] - Config.heightDistance, raceWay));//僵尸与植物底部对齐
        }
    }

    /**
     * 判断指定位置是否存在植物
     *
     * @param key          标识
     * @param raceWayIndex 需要检查的跑道
     * @return 不存在返回真，存在返回假
     */
    private boolean isPlantExist(int key, int raceWayIndex) {
        for (BaseModel mode : gameLayout4[raceWayIndex]) {
            if (mode instanceof Plantable) {
                if (key == ((Plantable) mode).getMapIndex()) {
                    return false;
                }
            }
        }
        return true;
    }
}
